{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "622cce72",
   "metadata": {},
   "source": [
    "理解了！这种模式类似于通过一个**配置对象**或**依赖注入**来创建另一个对象。下面我用一个更贴近实际的例子来说明：\n",
    "\n",
    "\n",
    "### **示例：游戏角色与武器系统**\n",
    "假设我们有一个 `Game` 类的实例，包含游戏的基本配置（如难度、资源路径等）。通过这个实例，我们可以创建不同的 `Weapon` 实例，每个武器会继承或使用游戏的部分配置。\n",
    "\n",
    "\n",
    "#### **1. 基础类定义**\n",
    "```python\n",
    "class Game:\n",
    "    def __init__(self, difficulty=\"easy\", resource_path=\"/assets\"):\n",
    "        self.difficulty = difficulty      # 游戏难度\n",
    "        self.resource_path = resource_path  # 资源路径\n",
    "        self.is_running = False         # 游戏运行状态\n",
    "\n",
    "    def start(self):\n",
    "        self.is_running = True\n",
    "        print(f\"游戏已启动，难度: {self.difficulty}\")\n",
    "\n",
    "    def stop(self):\n",
    "        self.is_running = False\n",
    "        print(\"游戏已停止\")\n",
    "\n",
    "\n",
    "class Weapon:\n",
    "    def __init__(self, game, name, damage):\n",
    "        self.game = game            # 持有对 Game 实例的引用\n",
    "        self.name = name            # 武器名称\n",
    "        self.damage = damage        # 基础伤害\n",
    "        self.is_equipped = False    # 是否装备状态\n",
    "\n",
    "    def equip(self):\n",
    "        if not self.game.is_running:\n",
    "            print(\"请先启动游戏！\")\n",
    "            return\n",
    "        self.is_equipped = True\n",
    "        print(f\"已装备武器: {self.name}\")\n",
    "\n",
    "    def attack(self):\n",
    "        if not self.is_equipped:\n",
    "            print(\"请先装备武器！\")\n",
    "            return\n",
    "        # 根据游戏难度调整伤害\n",
    "        multiplier = 1.5 if self.game.difficulty == \"hard\" else 1.0\n",
    "        actual_damage = self.damage * multiplier\n",
    "        print(f\"使用 {self.name} 攻击，造成 {actual_damage} 点伤害！\")\n",
    "```\n",
    "\n",
    "\n",
    "#### **2. 创建实例并说明关系**\n",
    "```python\n",
    "# 创建 Game 实例\n",
    "game = Game(difficulty=\"hard\", resource_path=\"/game/assets\")\n",
    "\n",
    "# 通过 Game 实例创建 Weapon 实例\n",
    "sword = Weapon(game, \"圣剑\", damage=100)\n",
    "bow = Weapon(game, \"神弓\", damage=80)\n",
    "\n",
    "# 比较属性差异\n",
    "print(\"Game 实例属性:\")\n",
    "print(f\"  - difficulty: {game.difficulty}\")\n",
    "print(f\"  - resource_path: {game.resource_path}\")\n",
    "print(f\"  - is_running: {game.is_running}\")\n",
    "\n",
    "print(\"\\nWeapon 实例属性:\")\n",
    "print(f\"  - name: {sword.name}\")\n",
    "print(f\"  - damage: {sword.damage}\")\n",
    "print(f\"  - is_equipped: {sword.is_equipped}\")\n",
    "print(f\"  - game.difficulty: {sword.game.difficulty}  # 引用 Game 实例的属性\")\n",
    "```\n",
    "\n",
    "\n",
    "### **3. 属性和方法的差异说明**\n",
    "| **对比项**       | **Game 实例**                  | **Weapon 实例**                |\n",
    "|------------------|------------------------------|-------------------------------|\n",
    "| **独有属性**      | `difficulty`, `resource_path` | `name`, `damage`, `is_equipped` |\n",
    "| **共享属性**      | 无                            | `game`（引用 Game 实例）       |\n",
    "| **独有方法**      | `start()`, `stop()`           | `equip()`, `attack()`          |\n",
    "| **状态依赖**      | 独立存在                       | 依赖 Game 实例的状态（如 `is_running`） |\n",
    "\n",
    "\n",
    "### **4. 交互示例**\n",
    "```python\n",
    "# 尝试攻击（未启动游戏）\n",
    "sword.attack()  # 输出: 请先装备武器！\n",
    "\n",
    "# 装备武器（未启动游戏）\n",
    "sword.equip()   # 输出: 请先启动游戏！\n",
    "\n",
    "# 启动游戏\n",
    "game.start()    # 输出: 游戏已启动，难度: hard\n",
    "\n",
    "# 再次装备并攻击\n",
    "sword.equip()   # 输出: 已装备武器: 圣剑\n",
    "sword.attack()  # 输出: 使用 圣剑 攻击，造成 150.0 点伤害！（难度调整后）\n",
    "\n",
    "# 修改游戏难度\n",
    "game.difficulty = \"easy\"\n",
    "sword.attack()  # 输出: 使用 圣剑 攻击，造成 100.0 点伤害！（难度调整后）\n",
    "```\n",
    "\n",
    "\n",
    "### **核心关系总结**\n",
    "1. **依赖注入**：`Weapon` 实例通过构造函数接收 `Game` 实例，形成**依赖关系**。\n",
    "2. **属性共享**：`Weapon` 可以访问 `Game` 的属性（如 `game.difficulty`），但不能直接修改 `Game` 的核心状态。\n",
    "3. **行为约束**：`Weapon` 的方法（如 `attack()`）依赖于 `Game` 的状态（如 `is_running`），确保操作合法性。\n",
    "4. **生命周期关联**：如果 `Game` 实例被销毁，`Weapon` 实例将失去引用，可能导致运行时错误。\n",
    "\n",
    "\n",
    "### **类似场景**\n",
    "- **Web 应用**：通过 `AppConfig` 实例创建 `DatabaseConnection`。\n",
    "- **图形系统**：通过 `Window` 实例创建 `Button` 或 `Panel` 控件。\n",
    "- **机器人控制**：通过 `Robot` 实例创建 `Tool` 附件（如机械臂、激光切割机）。\n",
    "\n",
    "这种模式实现了对象间的**松耦合**，允许一个对象（如 `Weapon`）使用另一个对象（如 `Game`）的服务，同时保持独立性。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "c744204a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Game 实例属性:\n",
      "  - difficulty: hard\n",
      "  - resource_path: /game/assets\n",
      "  - is_running: False\n",
      "\n",
      "Weapon 实例属性:\n",
      "  - name: 圣剑\n",
      "  - damage: 100\n",
      "  - is_equipped: False\n",
      "  - game.difficulty: hard  # 引用 Game 实例的属性\n"
     ]
    }
   ],
   "source": [
    "class Game:\n",
    "    def __init__(self, difficulty=\"easy\", resource_path=\"/assets\"):\n",
    "        self.difficulty = difficulty      # 游戏难度\n",
    "        self.resource_path = resource_path  # 资源路径\n",
    "        self.is_running = False         # 游戏运行状态\n",
    "\n",
    "    def start(self):\n",
    "        self.is_running = True\n",
    "        print(f\"游戏已启动，难度: {self.difficulty}\")\n",
    "\n",
    "    def stop(self):\n",
    "        self.is_running = False\n",
    "        print(\"游戏已停止\")\n",
    "\n",
    "\n",
    "class Weapon:\n",
    "    def __init__(self, game, name, damage):\n",
    "        self.game = game            # 持有对 Game 实例的引用\n",
    "        self.name = name            # 武器名称\n",
    "        self.damage = damage        # 基础伤害\n",
    "        self.is_equipped = False    # 是否装备状态\n",
    "\n",
    "    def equip(self):\n",
    "        if not self.game.is_running:\n",
    "            print(\"请先启动游戏！\")\n",
    "            return\n",
    "        self.is_equipped = True\n",
    "        print(f\"已装备武器: {self.name}\")\n",
    "\n",
    "    def attack(self):\n",
    "        if not self.is_equipped:\n",
    "            print(\"请先装备武器！\")\n",
    "            return\n",
    "        # 根据游戏难度调整伤害\n",
    "        multiplier = 1.5 if self.game.difficulty == \"hard\" else 1.0\n",
    "        actual_damage = self.damage * multiplier\n",
    "        print(f\"使用 {self.name} 攻击，造成 {actual_damage} 点伤害！\")\n",
    "\n",
    "game = Game(difficulty=\"hard\", resource_path=\"/game/assets\")\n",
    "\n",
    "# 通过 Game 实例创建 Weapon 实例\n",
    "sword = Weapon(game, \"圣剑\", damage=100)\n",
    "bow = Weapon(game, \"神弓\", damage=80)\n",
    "\n",
    "# 比较属性差异\n",
    "print(\"Game 实例属性:\")\n",
    "print(f\"  - difficulty: {game.difficulty}\")\n",
    "print(f\"  - resource_path: {game.resource_path}\")\n",
    "print(f\"  - is_running: {game.is_running}\")\n",
    "\n",
    "print(\"\\nWeapon 实例属性:\")\n",
    "print(f\"  - name: {sword.name}\")\n",
    "print(f\"  - damage: {sword.damage}\")\n",
    "print(f\"  - is_equipped: {sword.is_equipped}\")\n",
    "print(f\"  - game.difficulty: {sword.game.difficulty}  # 引用 Game 实例的属性\")\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7455e624",
   "metadata": {},
   "outputs": [],
   "source": [
    "sword.attack()  # 输出: 请先装备武器！\n",
    "\n",
    "# 装备武器（未启动游戏）\n",
    "sword.equip()   # 输出: 请先启动游戏！\n",
    "\n",
    "# 启动游戏\n",
    "game.start()    # 输出: 游戏已启动，难度: hard\n",
    "\n",
    "# 再次装备并攻击\n",
    "sword.equip()   # 输出: 已装备武器: 圣剑\n",
    "sword.attack()  # 输出: 使用 圣剑 攻击，造成 150.0 点伤害！（难度调整后）\n",
    "\n",
    "# 修改游戏难度\n",
    "game.difficulty = \"easy\"\n",
    "sword.attack()  # 输出: 使用 圣剑 攻击，造成 100.0 点伤害！（难度调整后）"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "env_py38",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
